from rest_framework import serializers

from drfstudy.models import Student, Classes

'''
第一个：对用户提交的数据进行校验 - 反序列化
第二个：对要返回的数据进行指定（转换）-序列化
'''


# class StudentSerializer(serializers.ModelSerializer):
#     # id = serializers.IntegerField(label='ID', read_only=True)  # 只读
#     # name = serializers.CharField(max_length=30, label="姓名")
#     # # required=False 不是必填项
#     # age = serializers.IntegerField(required=False, label="年龄")
#     # sex = serializers.IntegerField(required=True, label="性别")
#     # create_time = serializers.DateTimeField(required=False, label="创建时间")
#     #
#     # # update_time = serializers.DateTimeField(required=False, label="修改时间")
#     # # is_delete = serializers.BooleanField(required=False, default=False, label="逻辑删除")
#
#     # validated_data前端传入的数据，一个字典
#     # 因为继承的序列器的create方法，没有做任何的保存操作，不满足持久化数据的要求，需要重写
#     def create(self, validated_data):
#         return Student.objects.create(**validated_data)
#
#     # instance 实例对象 查询到的表数据， 例如查询到的id为1的学生
#     # validated_data 新数据 前端传过来的数据 类字典
#     def update(self, instance, validated_data):
#         # [键]取值方式 如果不存在会报错
#         # get方法可以自定义返回的值，键有对应的值，则返回值，如果没有则返回后面自定义的内容
#
#         # 获取name键对应的值，如果有的话代表修改了用户名，得到新的用户名
#         # 获取name键对应的值，如果没有则代表没有修改用户名，使用数据表里面原本的值
#         instance.name = validated_data.get("name", instance.name)
#         instance.age = validated_data.get("age", instance.age)
#         instance.sex = validated_data.get("sex", instance.sex)
#         # 通过模型对象做保存的操作 持久化数据
#         instance.save()
#         return instance


class StudentSerializer(serializers.ModelSerializer):
    # classes.name
    # 把模型的属性值作为来源
    # 添加额外的字段
    class_name = serializers.CharField(source='classes.name', read_only=True)

    # Meta 元数据类 数据来源模型是那个模型
    # 一些基本的数据校验
    class Meta:
        model = Student
        # 指定映射的字段，映射所有的字段，都会展示出来
        # fields = '__all__'
        # 指定只展示该两个字段给前端显示
        # fields = ["name", "age"]
        # 除去该字段不展示，其他的都展示
        exclude = ["is_delete"]

        # 添加额外的数据校验
        extra_kwargs = {
            "age": {
                'min_value': 1,
                'max_value': 150,
            },
            # 限制班级为只写操作
            'classes': {'write_only': True}

        }

    # 自动将用户传入的字段值作为参数传入到该方法
    # validate_你要验证的字段名
    # 属性级别的校验
    # def validate_name(self, value):
    #     if 'drf' not in value.lower():
    #         raise serializers.ValidationError("用户名需要包含drf")
    #     return value
    # 对象级别的校验
    # 把用户提交的所有数据传入到参数，字典类型
    # 可以一次性对多个字段进行校验 联动校验
    def validate(self, attrs):
        if 'drf' not in attrs.get('name').lower():
            raise serializers.ValidationError("用户名需要包含drf")

        if attrs.get("age") < 18:
            raise serializers.ValidationError("未成年人禁止使用")
        return attrs

    # 对前端提交的数据进行内容格式的校验 反序列化的操作


class StudentSerializerSimple(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ["id", "name", "age", "sex"]


class ClassesSerializer(serializers.ModelSerializer):
    # 添加一个额外的字段
    # 属性名就是管理器的名字
    # 把该班级的所有学生使用 StudentSerializer序列化器，进行序列化的操作
    # 用student_set保存
    # 序列化器的嵌套 在一个序列化器里面使用另一个序列化器
    student_set = StudentSerializerSimple(many=True, read_only=True)

    class Meta:
        model = Classes
        exclude = ["is_delete"]
